package com.arpa.wms.controller;

import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.arpa.core.web.MediaTypes;
import com.arpa.core.web.RestFulStatus;
import com.arpa.core.web.Result;
import com.arpa.ntocc.common.common.Page;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.cache.PartyCacheDO;
import com.arpa.ntocc.common.common.constant.StrConsts;
import com.arpa.ntocc.common.common.util.LogUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.dto.WarehouseAuthorizationJsonBean;
import com.arpa.ntocc.common.domain.entity.Client;
import com.arpa.ntocc.common.domain.entity.UserLogin;
import com.arpa.ntocc.common.domain.enums.ClientTypeEnum;
import com.arpa.ntocc.common.domain.vo.TreeData;
import com.arpa.ntocc.common.security.annotation.NeedLogin;
import com.arpa.ntocc.common.service.IClientService;
import com.arpa.ntocc.common.service.IUserLoginService;
import com.arpa.wms.domain.consts.NumConst;
import com.arpa.wms.domain.consts.PropertyConst;
import com.arpa.wms.domain.dto.WarehouseDTO;
import com.arpa.wms.domain.entity.Warehouse;
import com.arpa.wms.domain.enums.StatusEnum;
import com.arpa.wms.domain.vo.WarehouseVO;
import com.arpa.wms.service.IWarehouseService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import io.swagger.annotations.*;
import lombok.extern.log4j.Log4j2;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.arpa.ntocc.common.domain.dto.UserInfoDTO.AUTHORIZE_WAREHOUSE_CODES;


/**
 * <p>
 * 仓库 Controller
 * </p>
 *
 * @author LEO
 * @since 2020-08-03
 */
@Api(tags = "仓库管理")
@RestController
@RequestMapping(value = "/warehouse", produces = "application/json;charset=UTF-8")
@Log4j2
public class WarehouseController {

    private final IWarehouseService iWarehouseService;

    private final IClientService clientService;
    private final IUserLoginService userLoginService;
    private final PartyCache partyCache;

    public WarehouseController(IWarehouseService iWarehouseService, IClientService clientService, IUserLoginService userLoginService,
                               PartyCache partyCache) {
        this.iWarehouseService = iWarehouseService;
        this.clientService = clientService;
        this.userLoginService = userLoginService;
        this.partyCache = partyCache;
    }

    /**
     * 获取 仓库 列表
     *
     * @param warehouseDTO
     * @param request
     * @return
     */
    @ApiOperation(value = "获取 仓库 列表", notes = "获取 仓库 列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer ")
    })
    @ApiResponses(@ApiResponse(code = 0, message = "success", response = WarehouseVO.class))
    @NeedLogin
    @GetMapping()
    public Result list(WarehouseDTO warehouseDTO, HttpServletRequest request) {
        try {

            //通过登录选择的仓库过滤数据
            warehouseDTO.setGroupCode(UserUtil.getBranchCode());
            WarehouseVO warehouseVOSum = iWarehouseService.queryListSum(warehouseDTO);
            List<WarehouseVO> warehouseVOList = iWarehouseService.queryList(warehouseDTO);

            Page returnPage = new Page(warehouseDTO.getPageNum(), warehouseDTO.getPageSize());
            returnPage.setRecords(warehouseVOList);
            returnPage.setTotal(warehouseVOSum.getTotal());
            returnPage.setSumObject(warehouseVOSum);
            return Result.ok().data(returnPage);
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE,e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 添加 仓库
     *
     * @param entity  Warehouse
     * @param request
     * @return
     */
    @ApiOperation(value = "添加 仓库 ", notes = "添加 仓库 ")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer 123456"),
            @ApiImplicitParam(name = "deviceId", value = "设备id", paramType = "header", dataType = "string", defaultValue = "0000000000")
    })
    @NeedLogin
    @PostMapping()
    public Result create(@RequestBody @Validated(Warehouse.Save.class) Warehouse entity, HttpServletRequest request) {
        try {
            entity.setGroupCode(UserUtil.getBranchCode());
            entity.setStatus(StatusEnum.UNACTIVE.getValue());

            // 校验仓库编码、仓库名称、仓库类型
            Result validResult = iWarehouseService.validateWarehouse(entity);
            if (!validResult.isOk()) {
                return validResult;
            }

            iWarehouseService.save(entity);
            return Result.ok("添加成功");
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE,e);
            return Result.error(e.getMessage());
        }
    }


    /**
     * 获取仓库详情
     *
     * @param code
     * @param request
     * @return
     */
    @ApiOperation(value = "获取仓库详情", notes = "获取仓库详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer 123456"),
            @ApiImplicitParam(name = "deviceId", value = "设备id", paramType = "header", dataType = "string", defaultValue = "0000000000"),
            @ApiImplicitParam(name = "code", value = "仓库code", paramType = "path", dataType = "String")
    })
    @ApiResponses(@ApiResponse(code = 0, message = "success", response = Warehouse.class))
    @NeedLogin
    @GetMapping(value = "/{code}")
    public Result warehouse(@PathVariable String code, HttpServletRequest request) {
        try {
            Warehouse entity = iWarehouseService.getByCode(code);
            entity.setGroupCode(UserUtil.getBranchCode());
            return Result.ok().data(entity);
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE,e);
            return Result.error(e.getMessage());
        }
    }


    /**
     * 修改仓库
     *
     * @param entity  仓库
     * @param request
     * @return
     */
    @ApiOperation(value = "修改仓库", notes = "修改仓库")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer "),
            @ApiImplicitParam(name = "deviceId", value = "设备id", paramType = "header", dataType = "string", defaultValue = "0000000000")
    })
    @NeedLogin
    @PutMapping()
    public Result update(@RequestBody @Validated(Warehouse.Update.class)Warehouse entity, HttpServletRequest request) {
        Result validResult;
        if (StrUtil.isBlank(entity.getCode())) {
            return Result.error("code不能为空");
        }

        // 校验仓库编码、仓库名称、仓库类型
        validResult = iWarehouseService.validateWarehouse(entity);
        if (!validResult.isOk()) {
            return validResult;
        }

        // 校验“启用库位管理”，如果是刚关闭，则校验库存，并停用库区库位
        if(NumConst.NUM_ZERO.equals(entity.getLocationManagement())) {
            validResult = iWarehouseService.closeLocationManagement(entity);
            if (!validResult.isOk()) {
                return validResult;
            }
        }

        int updateNum = iWarehouseService.updateByCode(entity);
        if (updateNum == 0) {
            return Result.error("没有更新数据！code:" + entity.getCode());
        } else {
            return Result.ok("修改成功,更新" + updateNum + "条数据！");
        }
    }




    /**
     * 删除 仓库
     *
     * @param  codes
     * @param request
     * @return
     */
    @ApiOperation(value = "单条删除 仓库 ", notes = "删除 仓库 ", produces = MediaTypes.JSON_UTF_8)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer "),
            @ApiImplicitParam(name = "deviceId", value = "设备id", paramType = "header", dataType = "string", defaultValue = "0000000000"),
            @ApiImplicitParam(name = "codes", value = "仓库code", paramType = "query", dataType = "String")
    })
    @NeedLogin
    @DeleteMapping("")
    public Result delete(@RequestParam List<String> codes, HttpServletRequest request) {
        try {
            return iWarehouseService.deleteByCode(codes);
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE,e);
            return Result.error(e.getMessage());
        }
    }


    /**
     * 启用仓库
     *
     * @param codes
     * @param request
     * @return
     */
    @ApiOperation(value = "启用仓库", notes = "启用仓库")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer "),
            @ApiImplicitParam(name = "deviceId", value = "设备id", paramType = "header", dataType = "string", defaultValue = "0000000000")
    })
    @NeedLogin
    @PutMapping("/active")
    public Result active(@RequestParam List<String> codes, HttpServletRequest request) {
        int updateNum =  iWarehouseService.activeStatus(codes);
        int failNum = codes.size() - updateNum;
        return Result.ok("启用成功" + updateNum + "条；失败" + failNum + "条；");
    }

    /**
     * 停用仓库
     *
     * @param codes
     * @param request
     * @return
     */
    @ApiOperation(value = "停用仓库", notes = "停用仓库")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer "),
            @ApiImplicitParam(name = "deviceId", value = "设备id", paramType = "header", dataType = "string", defaultValue = "0000000000")
    })
    @NeedLogin
    @PutMapping("/unactive")
    public Result unactive(@RequestParam List<String> codes, HttpServletRequest request) {
        Map<String,Object> result = iWarehouseService.unactiveStatus(codes);
        List<String> msg = MapUtil.get(result,"msg",List.class);
        String message = "";
        if(IterUtil.isNotEmpty(msg)){
            for(String m: msg){
                message+="<br><font color='red'>仓库【"+m+"】停用失败，库存不为0;</font>";
            }
        }
        return Result.ok("停用成功" + (MapUtil.getInt(result, PropertyConst.SUCCESS)==null?0:MapUtil.getInt(result,PropertyConst.SUCCESS)) + "条；失败" + (MapUtil.getInt(result,"fail") == null ? 0 : MapUtil.getInt(result,"fail")) + "条；"+message);
    }


    /**
     * wms获取 仓库下拉列表数据
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "WMS获取仓库下拉列表数据", notes = "返回当前登录用户所属机构启用并开启库位管理的仓库信息,WMS使用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer ")
    })
    @ApiResponses(@ApiResponse(code = 0, message = "success", response = WarehouseVO.class))
    @NeedLogin
    @GetMapping("/chooseData")
    public Result chooseData(
            HttpServletRequest request) {
        try {
            List<WarehouseVO> warehouseVOList = iWarehouseService.findWarehouse();
            return Result.ok().data(warehouseVOList);
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE,e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * oms获取 仓库下拉列表数据
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "OMS获取仓库下拉列表数据", notes = "返回当前登录用户所属机构启用并开启库位管理的仓库信息,WMS使用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer ")
    })
    @ApiResponses(@ApiResponse(code = 0, message = "success", response = WarehouseVO.class))
    @NeedLogin
    @GetMapping("/omsChooseData")
    public Result omsChooseData(HttpServletRequest request) {
        try {
            List<WarehouseVO> warehouseVOList = iWarehouseService.findOmsWarehouse();
            return Result.ok().data(warehouseVOList);
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE,e);
            return Result.error(e.getMessage());
        }
    }


    /**
     * 获取仓库、货主级联数据
     * 用户添加账号授权使用
     *
     * @param userLoginType
     * @param request
     * @return
     */
    @ApiOperation(value = "获取仓库、货主级联数据", notes = "WMS添加账号授权时使用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer "),
            @ApiImplicitParam(name = "userLoginType", value = "账号类型：WAREHOUSE（仓库）/SHIPMENT（入驻商）/WAREHOUSE、SHIPMENT（仓库，入驻商）", required = true,paramType = "query", dataType = "string")
    })
    @ApiResponses(@ApiResponse(code = 0, message = "success", response = TreeData.class))
    @NeedLogin
    @GetMapping("/userLoginCascadeData")
    public Result cascadeData(String userLoginType,HttpServletRequest request) {
        List<TreeData> cascadeData = iWarehouseService.cascadeData(userLoginType);
        return Result.ok().data(cascadeData);
    }





    /**
     * WMS登录页面获取授权仓库列表
     *
     * @param client_id
     * @param client_secret
     * @param userLoginId
     * @param request
     * @return
     */
    @ApiOperation(value = "WMS、PDA登录页面获取授权仓库列表", notes = "仅限WMS、PDA登录页面仓库下拉列表框使用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "client_id", value = "客户端ID", required = true, paramType = "header", dataType = "string", defaultValue = ""),
            @ApiImplicitParam(name = "client_secret", value = "客户端安全码", required = true, paramType = "header", dataType = "string", defaultValue = ""),
            @ApiImplicitParam(name = "userLoginId", value = "登录账号", required = true, paramType = "query", dataType = "string", defaultValue = ""),
    })
    @GetMapping("/warehouseAuthorization")
    public Result cascadeData(@RequestHeader String client_id, @RequestHeader String client_secret, @RequestParam String userLoginId, HttpServletRequest request) {
        //校验客户端应用ID和安全码
        Client client = clientService.getClient(client_id, client_secret);
        if (client == null) {
            log.info(LogUtil.log("客户端应用ID【"+client_id+"】和安全码【"+client_secret+"】验证失败！"));
            return Result.error(RestFulStatus.OAUTH2_INVALID_CLIENT);
        }
        UserLogin userLogin = userLoginService.getUserLoginByUserLoginId(userLoginId);
        if(null==userLogin){
            log.error("登录账号【{}】不存在",userLoginId);
            return Result.ok();
        }
        if(StrUtil.equalsAny(client.getType(),ClientTypeEnum.WEB_WMS.getValue(),ClientTypeEnum.WMS_PDA.getValue())) {
            if (!StrUtil.equalsAny("admin", userLoginId, "super_admin")) {
                if (StrUtil.isNotBlank(userLogin.getPartyCode())) {
                    PartyCacheDO partyCacheDO = partyCache.get(userLogin.getPartyCode());
                    String authorizationWarehouse = partyCacheDO.getAuthorizationWarehouse();
                    List<String> authorizationWarehouseCodeStr = Lists.newArrayList();
                    if (StrUtil.isNotBlank(authorizationWarehouse)) {
                        String[] authorizationWarehouseCode = StrUtil.split(authorizationWarehouse, ",");
                        if (ArrayUtil.isNotEmpty(authorizationWarehouseCode)) {
                            authorizationWarehouseCodeStr =  Arrays.stream(authorizationWarehouseCode)
                                    .map(s -> StrUtil.unWrap(s, "[", "]")).collect(Collectors.toList());
                        }
                    }
                    List<Warehouse> warehouses = iWarehouseService.list(new LambdaQueryWrapper<Warehouse>().in(Warehouse::getCode,authorizationWarehouseCodeStr));
                    return Result.ok().data(warehouses);
                }
            } else {
                List<WarehouseVO> warehouseVOList = iWarehouseService.findAllWarehouse();
                return Result.ok().data(warehouseVOList);
            }
        }
        return Result.ok();
    }

  /*  *//**
     * WMS登录页面获取授权仓库列表
     *
     * @param client_id
     * @param client_secret
     * @param userLoginId
     * @param request
     * @return
     *//*
    @ApiOperation(value = "WMS、PDA登录页面获取授权仓库列表", notes = "仅限WMS、PDA登录页面仓库下拉列表框使用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "client_id", value = "客户端ID", required = true, paramType = "header", dataType = "string", defaultValue = ""),
            @ApiImplicitParam(name = "client_secret", value = "客户端安全码", required = true, paramType = "header", dataType = "string", defaultValue = ""),
            @ApiImplicitParam(name = "userLoginId", value = "登录账号", required = true, paramType = "query", dataType = "string", defaultValue = ""),
    })
    @GetMapping("/warehouseAuthorization")
    public Result cascadeData(@RequestHeader String client_id, @RequestHeader String client_secret, @RequestParam String userLoginId, HttpServletRequest request) {
        //校验客户端应用ID和安全码
        Client client = clientService.getClient(client_id, client_secret);
        if (client == null) {
            log.info(LogUtil.log("客户端应用ID【"+client_id+"】和安全码【"+client_secret+"】验证失败！"));
            return Result.error(RestFulStatus.OAUTH2_INVALID_CLIENT);
        }
        UserLogin userLogin = userLoginService.getUserLoginByUserLoginId(userLoginId);
        if(null==userLogin){
            log.error("登录账号【{}】不存在",userLoginId);
            return Result.ok();
        }
        if(StrUtil.equalsAny(client.getType(),ClientTypeEnum.WEB_WMS.getValue(),ClientTypeEnum.WMS_PDA.getValue())) {
            if (!StrUtil.equalsAny("admin", userLoginId, "super_admin")) {
                if (StrUtil.isNotBlank(userLogin.getWarehouseAuthorization())) {
                    List<WarehouseAuthorizationJsonBean> warehouseAuthorizationJsonBeans =
                            JSONUtil.toList(JSONUtil.parseArray(userLogin.getWarehouseAuthorization()), WarehouseAuthorizationJsonBean.class);
                    List<Warehouse> warehouses = warehouseAuthorizationJsonBeans.stream()
                            .map(r->iWarehouseService.getByCode(r.getWarehouse())).collect(Collectors.toList());
                    return Result.ok().data(warehouses);
                }
            } else {
                List<WarehouseVO> warehouseVOList = iWarehouseService.findAllWarehouse();
                return Result.ok().data(warehouseVOList);
            }
        }
        return Result.ok();
    }*/





    /**
     * WMS业务操作获取仓库数据
     * @return
     */
    @ApiOperation(value = "WMS业务操作获取仓库数据", notes = "仅限WMS业务操作页面下拉框使用。比如：" +
            "入库管理、出库管理中的列表、表单等页面使用，返回登录时选择的仓库信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "授权token", required = true, paramType = "header", dataType = "String", defaultValue = "Bearer ")
    })
    @ApiResponses(@ApiResponse(code = 0, message = "success", response = WarehouseVO.class))
    @NeedLogin
    @GetMapping("/business/warehouse")
    public Result businessChooseData() {
        return Result.ok().data(UserUtil.getAuthorizeWarehouseList());
    }



}
